package logic

import (
	"encoding/json"
	"regexp"
	"time"

	"gitee.com/leicc/go-orm"
	"gitee.com/leicc/go-orm/log"
	"gitee.com/leicc/go-app-core/models/im"
)

const offlineChanSize = 10240

type Store struct {
	chMsg chan ArgsOfflineMessages
}

var GStore *Store = nil

func init() {
	GStore = &Store{chMsg: make(chan ArgsOfflineMessages, offlineChanSize)}
}

//往管道写数据 发送私人消息
func (s *Store) Send(msgSt ArgsOfflineMessages) {
	defer func() {
		if err := recover(); err != nil {
			log.Write(log.ERROR, err)
		}
	}()
	select {
	case s.chMsg <- msgSt:
	default://执行失败的情况执行默认
		log.Write(log.ERROR, "发送离线消息持久化到数据库异常")
	}
}

//获取聊天目标的hashid，方便做分表策略
func (s *Store) GenTargetid(fromid int64, touserid int64) int64 {
	return (fromid + touserid) % 10000000000
}

//关闭管道连接
func (s *Store) Close()  {
	close(s.chMsg)
}

//客户端写数据的业务
func (s *Store) Persist() {
	sorm  := im.NewImMessage()
	rp, _ := regexp.Compile("^[\\da-zA-Z\\-]{16,}$")
	for {//循环接收数据，然后持久化到db当中
		msgSt, ok := <-s.chMsg
		if !ok {
			continue
		}
		sndUser, _ := json.Marshal(msgSt.User)
		toUser, _  := json.Marshal(msgSt.ToUser)
		if msgSt.TargetId < 1 { //产生分表的tagetid
			msgSt.TargetId = s.GenTargetid(msgSt.UserId, msgSt.ToUserId)
		}
		stime := time.Now().Unix()
		sorm.SetModTable(msgSt.TargetId)
		for _, message := range msgSt.Messages { //遍历插入离线消息
			if ok = rp.MatchString(message.Uuid); !ok {
				message.Uuid = GetUuidString()
			}
			msgStr, _ := json.Marshal(message)
			fields := orm.SqlMap{"seqno": message.Uuid, "isread": 0, "stime": stime, "userid": msgSt.UserId,
				"user": string(sndUser), "message": string(msgStr), "touserid": msgSt.ToUserId,
				"touser": string(toUser), "targetid": msgSt.TargetId, "type": msgSt.Type, "appid": GConfig.Appid}
			sorm.NewOne(fields, orm.SqlMap{"stime": stime})
		}
	}
}